package clue

import (
	"context"
	"encoding/json"
	"errors"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/clue"
	clueService "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/clue/clue"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/job_center"
	"git.myscrm.cn/golang/stark/v4"
)

type clueServer struct {
	clueService clueService.ClueServiceIface
	jobService  job_center.JobCenterServiceIface
}

func NewClueServer(
	clueService clueService.ClueServiceIface,
	jobService job_center.JobCenterServiceIface,
) pb.ClueServiceServer {
	return &clueServer{
		clueService: clueService,
		jobService:  jobService,
	}
}

func (s *clueServer) SaveClueContact(ctx context.Context, request *pb.SaveClueContactRequest) (*pb.SaveClueContactResponse, error) {
	id, err := s.clueService.SaveClueContact(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.SaveClueContactResponse{Id: id}, nil
}

func (s *clueServer) GetClueContactList(ctx context.Context, request *pb.GetClueContactListRequest) (*pb.GetClueContactListResponse, error) {
	resp, err := s.clueService.GetClueContactList(ctx, request)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *clueServer) DeleteClueContact(ctx context.Context, request *pb.DeleteClueContactRequest) (*pb.DeleteClueContactResponse, error) {
	err := s.clueService.DeleteClueContact(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.DeleteClueContactResponse{IsSuccess: true}, nil
}

func (s *clueServer) GetClueContactDetailById(ctx context.Context, request *pb.GetClueContactDetailByIdRequest) (*pb.GetClueContactDetailByIdResponse, error) {
	resp, err := s.clueService.GetClueContactDetailById(ctx, request)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *clueServer) SaveClueTracker(ctx context.Context, request *pb.SaveClueTrackerRequest) (*pb.SaveClueTrackerResponse, error) {
	trackerId, err := s.clueService.SaveClueTracker(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.SaveClueTrackerResponse{Id: trackerId}, nil
}

func (s *clueServer) GetClueTrackerList(ctx context.Context, request *pb.GetClueTrackerListRequest) (*pb.GetClueTrackerListResponse, error) {
	resp, err := s.clueService.GetClueTrackerList(ctx, request)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *clueServer) DeleteClueTracker(ctx context.Context, request *pb.DeleteClueTrackerRequest) (*pb.DeleteClueTrackerResponse, error) {
	err := s.clueService.DeleteClueTracker(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.DeleteClueTrackerResponse{IsSuccess: true}, nil
}

func (s *clueServer) ReplaceChargeUser(ctx context.Context, request *pb.ReplaceChargeUserRequest) (*pb.ReplaceChargeUserResponse, error) {
	err := s.clueService.ReplaceChargeUser(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.ReplaceChargeUserResponse{IsSuccess: true}, nil
}

func (s *clueServer) AddClueFollowRecord(ctx context.Context, request *pb.AddClueFollowRecordRequest) (*pb.AddClueFollowRecordResponse, error) {
	id, err := s.clueService.AddClueFollowRecord(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.AddClueFollowRecordResponse{Id: id}, nil
}

func (s *clueServer) GetClueFollowRecordList(ctx context.Context, request *pb.GetClueFollowRecordListRequest) (*pb.GetClueFollowRecordListResponse, error) {
	resp, err := s.clueService.GetClueFollowRecordList(ctx, request)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s *clueServer) SaveClue(ctx context.Context, request *pb.SaveClueRequest) (*pb.SaveClueResponse, error) {
	clueId, err := s.clueService.ClueSave(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc SaveClue request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	stark.Logger.Infof(ctx, "grpc SaveClue request:%#v succeed, clueId:%d", request, clueId)
	return &pb.SaveClueResponse{Id: clueId}, nil
}

func (s *clueServer) DeleteClue(ctx context.Context, request *pb.DeleteClueRequest) (*pb.DeleteClueResponse, error) {
	err := s.clueService.DeleteClue(ctx, request)
	if err != nil {
		return nil, err
	}
	return &pb.DeleteClueResponse{IsSuccess: true}, nil
}

func (s *clueServer) GetClueList(ctx context.Context, request *pb.GetClueListRequest) (*pb.GetClueListResponse, error) {
	resp, err := s.clueService.ClueList(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc GetClueList request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	stark.Logger.Infof(ctx, "grpc GetClueList request:%#v succeed", request)
	return resp, nil
}

func (s *clueServer) GetClueDetailByClueId(ctx context.Context, request *pb.GetClueDetailByClueIdRequest) (*pb.GetClueDetailByClueIdResponse, error) {
	resp, err := s.clueService.GetClueDetailByClueId(ctx, request.Id)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc GetClueDetailByClueId request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	stark.Logger.Infof(ctx, "grpc GetClueDetailByClueId request:%#v, resp:%#v", request, resp)
	return resp, nil
}

func (s *clueServer) GetInChargeUserList(ctx context.Context, request *pb.GetInChargeUserListRequest) (*pb.GetInChargeUserListResponse, error) {
	resp, err := s.clueService.GetInChargeUserList(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc GetInChargeUserList request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	return resp, nil
}

// AddClueSourceFollow 跟进添加线索
func (s *clueServer) AddClueSourceFollow(ctx context.Context, request *pb.AddClueSourceFollowRequest) (*pb.AddClueSourceFollowResponse, error) {
	isNewClue, err := s.clueService.AddClueSourceFollow(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc AddClueSourceFollow request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	return &pb.AddClueSourceFollowResponse{IsNewClue: isNewClue}, nil
}

// ExportClueList 导出线索
func (s *clueServer) ExportClueList(ctx context.Context, request *pb.ExportClueListRequest) (*pb.ExportClueListResponse, error) {
	listResp, err := s.clueService.ClueList(ctx, &pb.GetClueListRequest{
		Keyword:            request.Keyword,
		StatusList:         request.StatusList,
		AreaCodeList:       request.AreaCodeList,
		Page:               1,
		PageSize:           1,
		UseCase:            request.UseCase,
		InChargeUserIdList: request.InChargeUserIdList,
		Assigned:           request.Assigned,
	})
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc ExportClueList ClueList request:%+v, err:%s", request, err.Error())
		return nil, err
	}
	if listResp.Total == 0 {
		return nil, errors.New("导出数据为空")
	}

	requestBytes, _ := json.Marshal(request)

	jobId, err := s.jobService.NewJob(ctx, constants.JobMethodExport, constants.JobTypeClueExport, listResp.Total, string(requestBytes))
	if err != nil {
		stark.Logger.Errorf(ctx, "grpc ExportClueList NewJob request:%+v, err:%s", request, err.Error())
		return nil, err
	}

	_ = s.jobService.StartJob(ctx, jobId)

	return &pb.ExportClueListResponse{JobId: jobId, IsSucceed: true}, nil
}
